module.exports = app => {
    const express = require('express')
    // 子路由
    const router = express.Router({
        mergeParams: true
    })
    const Admin = require('../../models/Admin')
    const bcrypt = require('bcryptjs')
    const jwt = require('jsonwebtoken')
    const assert = require('http-assert')

    // 登录接口校验处理
    const auth = async (req, res, next) => {
        // 跳过jwt验证
        if (req.query.type == '1') {
            await next()
        } else {
            const author = String(req.headers.authorization || '').split(' ').pop()
            assert(author, 401, '请提供有效的 jwttoken')
            const { id } = jwt.verify(author, app.get('pwd'))
            assert(id, 401, '请先登录')
            req.user = Admin.findById(id)
            assert(req.user, 401, '请先登录')
            await next()
        }
    }
    // let Category = require('../../models/Category')
    // 创建分类信息接口
    router.post('/', async (req, res) => {
        let model = await req.Model.create(req.body)
        res.send(model)
    })
    // 获取分类信息接口
    router.get('/', async (req, res) => {
        let queryOptions = {}
        if (req.Model.modelName === 'Category') {
            queryOptions = {
                populate: 'parent'
            }
        }
        // 关联查询
        let model = await req.Model.find().setOptions(queryOptions).limit(100)
        res.send(model)
    })
    // 根据id查询分类信息接口
    router.get('/:id', async (req, res) => {
        let model = await req.Model.findById(req.params.id)
        res.send(model)
    })
    // 根据id更新分类信息接口
    router.put('/:id', async (req, res) => {
        await req.Model.findByIdAndUpdate(req.params.id, req.body)
        res.send({
            'message': 'ok'
        })
    })
    // 根据id删除分类信息接口
    router.delete('/:id', async (req, res) => {
        await req.Model.findByIdAndDelete(req.params.id, req.body)
        res.send({
            'message': 'ok'
        })
    })
    // 对所有的resource请求资源做统一的前置处理 => 中间件
    app.use('/admin/api/rest/:resource', auth, async (req, res, next) => {
        // inflection: 把字符串转成类名 npm i inflection 
        const modelName = require('inflection').classify(req.params.resource)
        req.Model = require(`../../models/${modelName}`)
        next()
    }, router)

    // 处理上传的图片 npm i multer
    const multer = require('multer')
    const MAO = require('multer-aliyun-oss');

    const upload = multer({
        storage: MAO({
            config: {
                region: 'oss-cn-beijing',
                accessKeyId: 'LTAI5tDf4DddVuV4kLaEekGw',
                accessKeySecret: 'ByImayjycZ9q5BpSjCitQX5Bj7fMPZ',
                bucket: 'wzry-demo'
            }
        })
    });
    // dist: 图片要保存的路径
    // let upload = multer({ dest: __dirname + '/../../uploads' })
    app.post('/admin/api/uploads', upload.single('file'), auth, async (req, res, next) => {
        // req本身是没有file属性的 经过multer处理后帮我们挂载上去的
        let file = req.file
        // file.url = `https://oss-cn-beijing.aliyuncs.com/uploads/${file.filename}`
        res.send(file)
        next()
    })

    // 登录接口
    app.post('/admin/api/login', async (req, res) => {
        // 1. 获取用户传过来的用户名和密码
        const { username, password } = req.body
        // 2. 根据用户名去数据库查询有没有该用户 => 没有则提示
        // select: 把密码也查询出来
        const user = await Admin.findOne({ username }).select('+password')
        assert(user, 422, '用户名不存在')
        // if (!user) {
        //     return res.status(422).send({
        //         message: '用户名不存在'
        //     })
        // }
        // 3. 获取到用户密码进行bcrypt解析 => 和用户传来的密码做校验
        // 参数1: 明文(用户传过来的密码) 参数2: 密文(数据库中保存的密码)
        const isvalid = bcrypt.compareSync(password, user.password)
        assert(isvalid, 422, '密码错误 请重新输入')
        // if (!isvalid) {
        //     return res.status(422).send({
        //         message: '密码错误 请重新输入'
        //     })
        // }
        // 4. 通过jwt(jsonwebtoken)设置token 给客户端
        // 目的: 后续客户端发起请求都要携带该token和服务端进行校验
        const token = jwt.sign({ id: user._id }, app.get('pwd'))
        // 4. 把结果返回给客户端
        res.send({ token, username })
    })

    // 错误函数 => 
    app.use(async (err, req, res, next) => {
        if (err.status || 500) {
            return res.status(err.status).send({ message: err.message })
        }
    })
}